;bytecode "instruction set" - assembly routines
;  core
;    dup drop over swap nip lit
;    ! @ +! ( zero page, 8-bit address )
;    alit +alit ( only way to get a value into A right now is with literals ) !+ @+ !a @a +a ( 16-bit address )
;        +@
;    push pop r
;    + - negate 1+ 1-
;    or xor and
;    = < > 0< 0> u< u>
;    -if if for next branch while
;    2* 2/
;    call exit
;  nes
;    ?
;  engine
;    ?
;    map
;      ?
;    entities
;      ?

;Virtual Machine Registers
;data stack     6502 stack
;RSP            zp pointer
;IPBASE         zp pointer
;A              zp pointer
;IP             Y, offset from (IPBASE)
;TOS            in stack
;A and X are free
;


_twolit:
  	ifetch
  	pha
_lit:
  	ifetch
  	pha
  	vmnext

_fetch:
        pla
        tax
  	lda  0,x
  	pha
  	vmnext


_store:
  	pla
  	tax
  	pla
	sta  0,x
  	vmnext

_plusstore:
	pla
	tax
	pla
	clc
	adc  0,x
	sta  0,x
	vmnext

_plus:
	pla
	tsx
	clc
	adc $101,x
	sta $101,x
	vmnext

_sbtrkt:
	pla
	sec
	sta VM_TEMP
	pla
	sbc VM_TEMP
	pha
	vmnext

_invert:
	pla
	eor #$ff
	pha
	vmnext

_negate:
	pla
        CLC 		;Ensure carry is clear
	EOR #$FF	;Invert all the bits
	ADC #1		;... and add one
	pha
	vmnext

_vm_or:
        pla
        tsx
	ora $101,X
	sta $101,X
	vmnext

_vm_xor:
        pla
        tsx
	eor $101,X
	sta $101,X
	vmnext

_vm_and:
        pla
        tsx
	and $101,X
	sta $101,X
	vmnext


_dup:
     	pla
	pha
	pha
	vmnext

_drop:
	pla
	vmnext

_over:
   pha
	tsx
	lda $103,x
 	sta $101,x
	vmnext

_swap:
	tsx
	lda $102,x
	pha
	lda $101,x
	sta $102,x
	pla
	sta $101,x
   vmnext

_nip:
	tsx
	lda $101,x
	sta $102,x
	pla
	vmnext

_vpstore:
   pla
	sta PPU_ADDR
	pla
	sta PPU_ADDR
	vmnext

_vstore:
	pla
	sta PPU_DATA
	vmnext

_oneplus:
	tsx
	inc $101,X
	vmnext

_oneminus:
	tsx
	dec $101,X
	vmnext

_propstore:
;	sty VM_TEMP
;	ifetch
;	tay
;	txa
;	sta (THIS),y
;	ldy VM_TEMP
;	pla
;	vmnext

_propfetch:
;	sty VM_TEMP
;	pha
;	ifetch
;	tay
;	lda (THIS),y
;	ldy VM_TEMP
;	vmnext


_twodiv
	pla
	CMP	#$80		; copy the sign bit to the carry bit
	ROR	A		; effectively perform a true ASR
	pha
	vmnext

_twomul
	tsx
	asl     $101,X
	vmnext

_fetchplus  ;3+6+2+3+2+3
	ldx	#0
	lda	(VM_A,x)
	inc	VM_A
	bne +
	inc	VM_A+1
+
	pha
	vmnext

_storeplus
	pla
	ldx	#0
	sta	(VM_A,x)
	inc	VM_A
	bne +
	inc	VM_A+1
+
	vmnext

_alit:
	ifetch
	sta VM_A
	ifetch
	sta VM_A+1
	vmnext

_fetcha:
	ldx	#0
	lda	(VM_A,x)
	pha
	vmnext

_plusfetch:
	pla
	tay
	lda   (VM_A),y
	pha
	vmnext

_storea:
	pla
	ldx	#0
	sta	(VM_A,x)
	vmnext

_plusalit:
	lda	VM_A
	clc
	adc	(VM_IPBASE),y
	sta	VM_A
	bcc +
	inc	VM_A+1
+
	iny
	vmnext

_plusa:
	pla
	clc
	adc	VM_A
	sta	VM_A
	bcc +
	inc	VM_A+1
+
	vmnext


_equals:
	pla
	tsx
	cmp 	$101,x
	bne	+
	lda	#$ff
	bne	++
+	lda	#$00
++	sta 	$101,x
	txs
	vmnext


_zgreater:
	lda	#0
	pha
_greater:
	pla
	tsx
	cmp 	$101,x
	bpl	+
	lda	#$ff
	bne	++
+	lda	#$00
++	sta 	$101,x
	txs
	vmnext

_zless:
	lda	#0
	pha
_less:
	pla
	tsx
	cmp 	$101,x
	bcs	+        ; TOS > 2OS
	lda	#$00
	beq	++
+	lda	#$ff
++	sta 	$101,x
	txs
	vmnext



_uless:
	pla
	tsx
	cmp 	$101,x
	bcs	+
	lda	#$ff
	bne	++
+	lda	#$00
++	sta 	$101,x
	txs
	vmnext

_ugreater:
	pla
	tsx
	cmp 	$101,x
	bcc	+
	lda	#$ff
	bne	++
+	lda	#$00
++	sta 	$101,x
	txs
	vmnext


; branch instructions are relative.  a literal in the instruction stream is added to Y.
_iff:
	pla
	beq	+
	iny
	vmnext
+
	tya
	clc
	adc	(VM_IPBASE),y
	tay
	vmnext

_mif:
	pla
	bne	+
	iny
	vmnext
+	tya
	clc
	adc	(VM_IPBASE),y
	tay
	vmnext


_for:
	pla
	dec	VM_RSP
	ldx	VM_RSP
	sta	0,x
	dec     0,x
	vmnext

_next:
	ldx	VM_RSP
	dec	0,x
	beq	+
_branch:
	tya
	clc
	adc	(VM_IPBASE),y
	tay
-	vmnext
+	inc	VM_RSP
	iny
	vmnext

_while: beq _branch
	iny
	vmnext



